﻿using UnityEngine;
namespace FrameWorkSong
{
    public static class VectorExtention
    {
        /// <summary>
        /// 角度旋转
        /// </summary>
        /// <param name="vector3"></param>
        /// <param name="angle">旋转角度</param>
        /// <param name="center">旋转中心点</param>
        /// <param name="direction">旋转轴</param>
        /// <returns></returns>
        public static Vector3 ToAngle(this Vector3 vector3, float angle, Vector3 center, Vector3 direction)
        {
            Vector3 pos = center;
            Quaternion quaternion = Quaternion.AngleAxis(angle, direction);
            Matrix4x4 matrix = new Matrix4x4();
            matrix.SetTRS(pos, quaternion, Vector3.one);
            vector3 = matrix.MultiplyPoint3x4(vector3);
            return vector3;
        }

        /// <summary>
        /// 矩阵变换
        /// </summary>
        /// <param name="vector3"></param>
        /// <param name="location">位置</param>
        /// <param name="direction">旋转向量</param>
        /// <returns></returns>
   
       public static Vector3 FromToMoveRotation(this Vector3 vector3, Vector3 location, Vector3 direction)
        {
            return vector3.FromToMoveRotation(location, direction,Vector3.one);
        }
        public static Vector3 FromToMoveRotation(this Vector3 vector3, Vector3 location, Vector3 direction,Vector3 scale)
        {
            
            Matrix4x4 matrix = Matrix4x4.identity;
            Quaternion quaternion = Quaternion.FromToRotation(Vector3.forward, direction);
            //Quaternion quaternion;
            //if (direction.y>0.5|| direction.y <- 0.5)
            //{
            //    quaternion = Quaternion.LookRotation(direction, Vector3.forward);
            //}
            //else
            //{
            //    quaternion = Quaternion.LookRotation(direction, Vector3.up);
            //}
              
         

            matrix.SetTRS(location, quaternion, scale);
            vector3 = matrix.MultiplyPoint3x4(vector3);
            
            return vector3;
        }

    

        /// <summary>
        /// 得到平面投影向量
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public static Vector3 GetPlaneVector(this Vector3 vector3)
        {
            return new Vector3(vector3.x, 0, vector3.z);
        }
        /// <summary>
        /// 得到向量上的投影
        /// </summary>
        /// <param name="vector3"></param>
        /// <param name="ProjectionVec">单位投影向量</param>
        /// <returns></returns>
        public static Vector3 GetProjectionVector(this Vector3 vector3,Vector3 ProjectionVec)
        {
            float ProjectionMagnitude = vector3.GetProjectionMagnitude(ProjectionVec);
            return ProjectionMagnitude * ProjectionVec;
        }
        /// <summary>
        /// 得到向量上的投影向量的模长
        /// </summary>
        /// <param name="vector3"></param>
        /// <param name="ProjectionVec">单位投影向量</param>
        /// <returns></returns>
        public static float GetProjectionMagnitude(this Vector3 vector3, Vector3 ProjectionVec)
        {
            //投影向量的单位向量
            float CosAngle = Vector3.Dot(vector3.normalized, ProjectionVec);
            return CosAngle * vector3.magnitude;
        }

        /// <summary>
        /// 两点得到抛物线点
        /// </summary>
        /// <param name="originPoint">起点</param>
        /// <param name="endPoint">终点</param>
        /// <param name="density">抛物线段数</param>
        /// <param name="p">焦准距</param>
        /// <returns></returns>
        public static Vector3[] GetParabolaPoints( Vector3 originPoint, Vector3 endPoint, int density, float p = 0)
        {
            Vector3 originPlanePoint = GetPlaneVector(originPoint);
            Vector3 endPlanePoint = GetPlaneVector(endPoint);
            float xzMagnitude = Vector3.Distance(originPlanePoint, endPlanePoint);
            float xzUnit = xzMagnitude / density;
            float a;
            if (p == 0)
            {
                a = -2 /  xzMagnitude;
            }
            else
            {
                a = -1 / (2 * p);
            }
            float yMagnitude = (endPoint - originPoint).y;
            float b = (yMagnitude - (xzMagnitude * xzMagnitude * a)) / xzMagnitude;

            Vector3[] parabolaPoint = new Vector3[density + 1];
            Vector3 xzUnitVec = (endPlanePoint - originPlanePoint) / density;
            for (int i = 0; i <= density; i++)
            {
                float xz = xzUnit * i;
                float y = (a * xz * xz) + b * xz;
                Vector3 yVec = new Vector3(0, y, 0);
                parabolaPoint[i] = originPoint + (xzUnitVec * i) + yVec;
            }
            return parabolaPoint;
        }
    }
}
